/*
* dart是脚本语言可以不定义类型，自动推断类型
*/
void main() {
  // 声明变量，对于局部变量推荐使用var
  var name = "fauks";
  dynamic age = 11;
  //使用强类型定义，Dart中无论对象、数字、方法都是对象默认值为null
  String address = "qd";
  int flag = 1;

  /*
  *  1.const值不变一开始就需要赋值，常量值；是编译时常量，编译时值就确定支持类型推断
  *     具有传递性，例如声明一个数组使用const限定，数组的元素也不可能更改
  *  2.final开始可以不赋值只能赋值一次；是运行时常量，可以通过运算、函数赋值
        并且final是惰性初始化，在运行时第一次使用前才初始化，不具有传递性声明的数组
        也可以修改
  */
  // final是运行时常量，编译不会报错
  final finalDate = new DateTime.now(); //正确，在第一次使用前赋值一次，与编译器无关
  print('$finalDate');
  //const constDate = new DateTime.now();//编译报错,因为这是编译时常量，值可变编译报错
  // const的使用场景 const可以省略
  const p1 = const Person("fauks");
  const p2 = Person("fauks");
  // 指向同一对象，节省对内存
  print(identical(p1, p2)); // true

  // intList的值为常量数组，而intList是变量所以引用可以重新赋值，编译通过
  var intList = const [];
  intList = [1, 2];
  // 相当于以下声明
  const temp = [];
  var doubleList = temp;
  doubleList = [1.0, 2.0];
  // temp本身使用const修饰，所以不可改变引用
  // temp = [1.0, 2.0];

  // 列表 List
  List nameList = ["fauks", "jay", "mj"];
  print("列表长度：${nameList.length}");
  for (var value in nameList) {
    print(value);
  }

  // 集合set，无序且不可重复
  // 集合set、映射map都使用{},而列表List使用[]
  Set addressSet = {"青岛", "威海", "烟台"};
  print(addressSet.contains("青岛"));
  print("集合长度：${addressSet.length}");

  // 使用Set集合对List列表去重
  List<String> names = ["fauks", "jay", "mj", "fauks"];
  names = Set<String>.from(names).toList();
  print("去重后的names = $names");

  // 映射
  Map stuClass = {"x001": "三年二班", "x002": "一年三班"};

  stuClass.clear();
  print(stuClass.length);

  // 三目运算符
  String desc = "";
  print(desc != null ? desc : "good boy");
  // 三木运算符可以简写，desc不为null则输出desc，如果为空输出bad girl
  print(desc ?? "bad girl");

  // Dart使用utf-16表示字符串，对于超过16位的可以使用Runes类型
  // 输出32位Unicode字符，\uXXXX,X为16进制
  var hearLogo = "\u2665";
  print(hearLogo);
  // 对于不是4个字符的，使用大括号包裹
  Runes runes = new Runes('\u{1f47b}');
  print(runes);

  String testRune = "fauks";
  // runes返回unicode字符编号 123 167之类的
  print(testRune.runes.map((e) => String.fromCharCode(e)).toList());
}

/*
* 一个类同时new两次，如果是同一对象
* 可以使用const修饰构造函数
* */
class Person {
  final String name;

  const Person(this.name);
}
